﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Platform.Storage.Redis.Messages
{
	public class ChannelNotificationMessage : RedisMessageBase<IEnumerable<Notification>>
	{
		public ChannelNotificationMessage( RedisMessageChannel channel )
			: base( channel, String.Empty, ( string[] )null )
		{ }

		protected override IEnumerable<Notification> GetReply( Func<RedisReplyLine> nextLine )
		{
			var headerLine = nextLine();

			Trace.Assert( headerLine.Reply == RedisReplyStatus.Collection );
			int lineCount = Convert.ToInt32( headerLine.Message );

			while ( lineCount > 0 )
			{
				var channelLine = nextLine();
				if ( this.IsNotificationLine( channelLine ) )
				{
					// Uma notificacao
					var msgLine = nextLine();

					Trace.Assert( channelLine.Reply == RedisReplyStatus.CollectionItem );
					Trace.Assert( channelLine.Reply == RedisReplyStatus.CollectionItem );

					yield return new Notification( channelLine.Message, msgLine.Message );
				}
				else
					nextLine(); // apenas consome a proxima linha que faz parte da mensagem

				lineCount -= 2;
			}
		}

		private bool IsNotificationLine( RedisReplyLine line )
		{
			return line.Reply == RedisReplyStatus.CollectionItem
				&& !(
					line.Message.Equals( "message", StringComparison.InvariantCultureIgnoreCase )
					|| line.Message.Equals( "pmessage", StringComparison.InvariantCultureIgnoreCase )
					|| line.Message.Equals( "subscribe", StringComparison.InvariantCultureIgnoreCase )
					|| line.Message.Equals( "psubscribe", StringComparison.InvariantCultureIgnoreCase ) );
		}

		public override string ToWireMessage()
		{
			return String.Empty;
			//return base.ToWireMessage();
		}
	}

	public class Notification
	{
		public Notification(string channel, string message)
		{
			this.Channel = channel;
			this.Message = message;
		}

		public string Channel
		{ get; private set; }

		public string Message
		{ get; private set; }
	}
}
